package com.htfyun.roobofactory.view;

/**
 * @author Jose Davis Nidhin
 */

import android.content.Context;
import android.graphics.Color;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;


import java.io.IOException;
import java.util.List;

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    public final static String TAG = "CameraPreview";

    SurfaceHolder mHolder;
    Camera mCamera = null;

    private Size mPreviewSize = null;
    List<Size> mSupportedPreviewSizes = null;
    private int maxFPS = 0;

    public CameraPreview(Context context, Camera camera) {
        super(context);

        mCamera = camera;

        mHolder = getHolder();

        mHolder.addCallback(this);

        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        setZOrderMediaOverlay(true);

        setBackgroundColor(Color.TRANSPARENT);

        if (mCamera != null) {
            mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();

        }

    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // We purposely disregard child measurements because act as a
        // wrapper to a SurfaceView that centers the camera preview instead
        // of stretching it.
        final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        setMeasuredDimension(width, height);

        if (mSupportedPreviewSizes != null) {
            mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        cameraStartPreview(holder);
    }



    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {


        if (mHolder.getSurface() == null || mCamera == null) {

            return;

        }

        try {

            mCamera.stopPreview();

        } catch (Exception e) {

        }

        cameraStartPreview(mHolder);

    }

    private void cameraStartPreview(SurfaceHolder holder) {

        if (mCamera == null) {
            return;
        }
        try {
            if (mCamera != null) {

                mCamera.setPreviewDisplay(holder);

                initCameraParameters();
                mCamera.startPreview();

            }
        } catch (IOException e) {
            Log.e(TAG, "Errorstarting camera preview: " + e.getMessage());
        }
    }

    private void initCameraParameters() {
        if (mCamera == null || mPreviewSize == null) {
            return;
        }

        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);

        List<int[]> fpsRange = parameters.getSupportedPreviewFpsRange();
        for (int[] f : fpsRange) {
            if (f[1] > maxFPS) {
                maxFPS = f[1];
            }
        }
        parameters.setPreviewFrameRate(maxFPS);

        mCamera.setParameters(parameters);

    }


    /*
     *  D/DualCamera( 5874): support-preview-size:1920x1080
        D/DualCamera( 5874): support-preview-size:1280x720
        D/DualCamera( 5874): support-preview-size:640x480
        D/DualCamera( 5874): support-preview-size:640x360
        D/DualCamera( 5874): support-preview-size:352x288
        D/DualCamera( 5874): support-preview-size:320x240
        D/DualCamera( 5874): support-preview-size:320x180
        D/DualCamera( 5874): support-preview-size:176x144
        D/DualCamera( 5874): support-preview-size:160x120
        D/DualCamera( 5874): support-preview-size:1920x1080
        D/DualCamera( 5874): optimalSize:640x480,windowsize:854x420
     */
    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) w / h;
        if (sizes == null) return null;

        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            double ratio = (double) size.width / size.height;
//            Log.d(TAG, "support-preview-size:" + size.width + "x" + size.height);
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }

        /*
        20170322 :  optimalSize:1280x720,windowsize:1280x682
         */
        Log.d(TAG, "optimalSize:" + optimalSize.width + "x" + optimalSize.height +
                ",windowsize:" + w + "x" + h);

        // 20170322,we may use the LQ-CAEMRA,don't support 1080P.
//        optimalSize.width = 1920;
//        optimalSize.height = 1080;
        return optimalSize;
    }

    public Size getmPreviewSize() {
        return mPreviewSize;
    }

    public int getMaxFPS() {
        return maxFPS;
    }
}
